package entity;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import util.UtilData;
import exceptions.ServiceException;

@Entity
public class Fatura extends EntityManaged implements Serializable,
		Comparable<Fatura> {

	private static final long serialVersionUID = 1082824403447060113L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	private Integer anoMesReferencia;

	@Transient
	private Date dataVencimento;
	
	@Transient
	private Conta contaPagamento;

	@Temporal(value = TemporalType.DATE)
	private Date dataFechamento;

	@OneToMany(mappedBy = "fatura", fetch = FetchType.EAGER)
	private List<ParcelaTransacao> listaParcelas;

	@Transient
	private BigDecimal valorTotal = BigDecimal.ZERO;

	@ManyToOne
	private ContaCredito contaCredito;

	private boolean faturaFechada;

	@Transient
	private final SimpleDateFormat SDF_ANO_MES = new SimpleDateFormat("yyyyMM");
	
	@Transient
	private final SimpleDateFormat SDF_MES_ANO = new SimpleDateFormat("MMM yyyy");

	@Override
	public Serializable getId() {
		return id;
	}

	public Date getDataReferencia() {

		try {
			return SDF_ANO_MES.parse(anoMesReferencia.toString());
		} catch (ParseException e) {
			throw new ServiceException();
		}
	}

	@Transient
	public Date getDataInicioLancamentos() {
		int diaFechamento = contaCredito.getDiaFechamentoFatura();
		final Calendar dataInicioFatura = UtilData
				.getCalendar(getDataReferencia());
		dataInicioFatura.set(Calendar.DAY_OF_MONTH, diaFechamento + 1);
		dataInicioFatura.add(Calendar.MONTH, -2);

		return dataInicioFatura.getTime();
	}

	@Transient
	public Date getDataFimLancamentos() {
		final Calendar dataFimFatura = UtilData
				.getCalendar(getDataReferencia());

		int diaFechamento = contaCredito.getDiaFechamentoFatura();

		dataFimFatura.set(Calendar.DAY_OF_MONTH, diaFechamento);
		dataFimFatura.add(Calendar.MONTH, -1);
		return dataFimFatura.getTime();
	}

	public List<ParcelaTransacao> getListaParcelas() {
		return listaParcelas;
	}

	public void setListaParcelas(List<ParcelaTransacao> listaParcelas) {
		this.listaParcelas = listaParcelas;
	}

	public BigDecimal getValorTotal() {
		return valorTotal;
	}

	public Integer getAnoMesReferencia() {
		return anoMesReferencia;
	}

	public void setAnoMesReferencia(Integer anoMesReferencia) {
		this.anoMesReferencia = anoMesReferencia;
	}

	public boolean isFaturaFechada() {
		return faturaFechada;
	}

	public void setFaturaFechada(boolean faturaFechada) {
		this.faturaFechada = faturaFechada;
	}

	@Override
	public int compareTo(Fatura o) {

		return this.anoMesReferencia.compareTo(o.anoMesReferencia);

	}

	public void setValorTotal(BigDecimal valorTotal) {
		this.valorTotal = valorTotal;
	}

	public ContaCredito getContaCredito() {
		return contaCredito;
	}

	public void setContaCredito(ContaCredito contaCredito) {
		this.contaCredito = contaCredito;
	}

	public Date getDataFechamento() {
		return dataFechamento;
	}

	public void setDataFechamento(Date dataFechamento) {
		this.dataFechamento = dataFechamento;
	}

	public Date getDataVencimento() {
		return dataVencimento;
	}

	public void setDataVencimento(Date dataVencimento) {
		this.dataVencimento = dataVencimento;
	}

	public Conta getContaPagamento() {
		return contaPagamento;
	}

	public void setContaPagamento(Conta contaPagamento) {
		this.contaPagamento = contaPagamento;
	}

}
